﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;
using StyleMVVM.DependencyInjection;

namespace StyleMVVM.WCF.Extensions
{
	public class InjectionServiceHost : ServiceHost
	{
		protected IDependencyInjectionContainer container;
		protected Type serviceType;

		public InjectionServiceHost(IDependencyInjectionContainer container, Type serviceType, params Uri[] baseAddresses)
			: base(serviceType, baseAddresses)
		{
			this.container = container;
			this.serviceType = serviceType;
		}

		protected override void OnOpening()
		{
			if (Description.Behaviors.Find<InjectionServiceBehavior>() == null)
			{
				Description.Behaviors.Add(new InjectionServiceBehavior(container));
			}

			base.OnOpening();
		}

		protected virtual void ApplyContractBehaviors()
		{
			IEnumerable<IContractBehavior> contractBehaviors =
				container.LocateAllWithContext<IContractBehavior>(CreateInjectionContext());

			foreach (IContractBehavior contractBehavior in contractBehaviors)
			{
				foreach (ContractDescription contract in ImplementedContracts.Values)
				{
					contract.Behaviors.Add(contractBehavior);
				}
			}
		}

		protected virtual void ApplyServiceBehaviors()
		{
			IEnumerable<IServiceBehavior> serviceBehaviors =
				container.LocateAllWithContext<IServiceBehavior>(CreateInjectionContext());

			foreach (IServiceBehavior serviceBehavior in serviceBehaviors)
			{
				Description.Behaviors.Add(serviceBehavior);
			}
		}

		protected virtual IInjectionContext CreateInjectionContext()
		{
			IInjectionContext context = container.CreateInjectionContext();

			context.SetConditionValue("ServiceType", serviceType);

			return context;
		}
	}
}